package com.tom.architect02.zframework.hook.hook2;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import androidx.annotation.NonNull;

import com.example.lib_personal.LoginActivity;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

/**
 * Added by Tom on 2024/04/02.
 * 动态代理+ Hook。
 */
public class HookUtils9 {
    private Context context;
    private Class<?> proxyActivity;

    public HookUtils9(Context context, Class<?> proxyActivity) {
        this.context = context;
        this.proxyActivity = proxyActivity;
    }
    // getService()-- get-- create()--- mInstance.

    public void hookAms() throws Exception {
        Class ActivityManagerClz = Class.forName("android.app.ActivityManager");
        Field IActivityManagerSingletonField = ActivityManagerClz.getDeclaredField("IActivityManagerSingleton");
        IActivityManagerSingletonField.setAccessible(true);
        // 拿到系统的对象（还原）
        // 返回原来的对象。static，直接传null， 拿里面的静态成员(已赋值了)
        Object IActivityManagerSingletonObj = IActivityManagerSingletonField.get(null);
        Class SingletonClz = Class.forName("android.util.Singleton");
        // 反射拿到Field： mInstance
        Field mInstanceField = SingletonClz.getDeclaredField("mInstance");
        mInstanceField.setAccessible(true); // binder：ActivityManagerServiceProxy
        Object IActivityManagerObj = mInstanceField.get(IActivityManagerSingletonObj); //
        IActivityManagerObj.hashCode();

        // 处理系统的Singleton，动态代理。
        Class IActivityManagerClz = Class.forName("android.app.IActivityManager");
        Object proxyIActivityManager = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                new Class[]{IActivityManagerClz}, new AmsInvocationHandler(IActivityManagerObj));
        // 替代系统变量
        mInstanceField.setAccessible(true);
        // 给对象IActivityManagerSingleton 的 成员mInstanceField 赋值 proxyIActivityManager
        mInstanceField.set(IActivityManagerSingletonObj, proxyIActivityManager);
    }


    public void hookSystemHandler() throws Exception {
        // 1.先拿到 ActivityThread
        Class ActivityThreadClz = Class.forName("android.app.ActivityThread");
        Field field = ActivityThreadClz.getDeclaredField("sCurrentActivityThread");
        field.setAccessible(true);
        Object ActivityThreadObj = field.get(null);
        ActivityThreadObj.hashCode();
        // 2.进而拿到mH
        Field mHField = ActivityThreadClz.getDeclaredField("mH");
        mHField.setAccessible(true);
        Handler mHObj = (Handler) mHField.get(ActivityThreadObj);

        // 3.实例化mH的Callback，Handler里面的mCallback
        Field mCallbackField = Handler.class.getDeclaredField("mCallback");
        mCallbackField.setAccessible(true);
        ProxyHandlerCallback proxyHandlerCallback = new ProxyHandlerCallback();
        mCallbackField.set(mHObj, proxyHandlerCallback);
    }




    // 非动态代理，也用到了hook思想---->
    private class ProxyHandlerCallback implements Handler.Callback {
        private int CODE_EXECUTE_TRANSACTION = 159;

        @Override
        public boolean handleMessage(@NonNull Message msg) {
            if (msg.what == CODE_EXECUTE_TRANSACTION) {
                Log.i("TAG", "handleMessage:" + msg.obj.getClass().toString());
                try {
                    // android.app.servertransaction.ClientTransaction
                    Class ClientTransactionClz = Class.forName("android.app.servertransaction.ClientTransaction");
                    if (!ClientTransactionClz.isInstance(msg.obj)) return false;
                    Class LaunchActivityItemClz = Class.forName("android.app.servertransaction.LaunchActivityItem");
                    Field mActivityCallbacksField = ClientTransactionClz.getDeclaredField("mActivityCallbacks");
                    mActivityCallbacksField.setAccessible(true);

                    // mActivityCallbacks
                    Object mActivityCallbacksObj = mActivityCallbacksField.get(msg.obj);
                    List list = (List) mActivityCallbacksObj;
                    if (list.size() == 0) return false;
                    Object LaunchActivityItemObj = list.get(0); // 判断是否是 LaunchActivityItem
                    if (!LaunchActivityItemClz.isInstance(LaunchActivityItemObj)) return false;

                    // 保证一定是startActivity。将intent设置回来。
                    Field mIntentField = LaunchActivityItemClz.getDeclaredField("mIntent");
                    mIntentField.setAccessible(true);
                    Intent mIntent = (Intent) mIntentField.get(LaunchActivityItemObj);
                    Intent realIntent = mIntent.getParcelableExtra("oldIntent");
                    if (realIntent != null) {
                        // 设置成未注册的SecondActivity。绕开Manifest注册。
                        // 登录判断。
                        SharedPreferences share = context.getSharedPreferences("david", Context.MODE_PRIVATE);
                        if (share.getBoolean("login", false)) {
                            // 已经登录了
                            mIntent.setComponent(realIntent.getComponent());
                        } else { // 需要登录。
                            ComponentName componentName = new ComponentName(context, HookLoginActivity.class);
                            // 将意图，再传递给LoginActivity。登录后做页面跳转。
                            mIntent.putExtra("extraIntent", realIntent.getComponent().getClassName());
                            mIntent.setComponent(componentName);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return false; // hook不能影响系统正常的执行。
        }
    }

    // 动态代理：处理器
    class AmsInvocationHandler implements InvocationHandler {
        // 被代理的对象
        private Object iActivityManagerObj;
        public AmsInvocationHandler(Object IActivityManagerObj) {
            this.iActivityManagerObj = IActivityManagerObj;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if ("startActivity".equals(method.getName())) {
                Intent intent = null;
                int index = 0;
                for (int i = 0; i < args.length; i++) {
                    Object arg = args[i];
                    if (arg instanceof Intent) {
                        intent = (Intent) args[i];
                        index = i;
                        break;
                    }
                }
                Intent proxyIntent = new Intent();
                // 替换意图(隐藏意图)
                ComponentName componentName = new ComponentName(context, proxyActivity);
                proxyIntent.setComponent(componentName);
                // 隐藏真实意图, 启动未注册的activity。将proxyActivity替换为真实的界面。
                proxyIntent.putExtra("oldIntent", intent);
                args[index] = proxyIntent;
            }
//            Log.i("TAG", "invoke:" + method.getName());
            return method.invoke(iActivityManagerObj, args);
        }
    }

}

